package com.core.db.require;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.core.db.annotation.Column;
import com.core.db.annotation.Table;
import com.core.db.condition.Condition;

/**
 * sql 拼装器
 * 
 * @author 殷田
 *
 */
public class Assembler
{
	public static Require query( Class< ? > clazz, Condition cond )
	{
		return new Select( parseTable( clazz ), parseColumnsData( clazz ), cond );
	}

	public static Require insert( Object obj )
	{
		return new Insert( parseTable( obj ), parseColumnsData( obj ) );
	}

	public static Require delect( Class< ? > clazz, Condition cond )
	{
		return new Delect( parseTable( clazz ), parseColumnsData( clazz ), cond );
	}

	public static Require update( Object obj, Condition cond )
	{
		return new Update( parseTable( obj ), parseColumnsData( obj ), cond );
	}

	private static String parseTable( Object obj )
	{
		return parseTable( obj.getClass() );
	}

	private static String parseTable( Class< ? > clazz )
	{
		if ( !clazz.isAnnotationPresent( Table.class ) )
		{
			return null;
		}
		Table table = ( Table ) clazz.getAnnotation( Table.class );
		return table.value();
	}

	public static List< ColumnDescribe > parseColumnsData( Class< ? > clazz )
	{
		List< ColumnDescribe > describes = new ArrayList< ColumnDescribe >();
		Field[] fields = clazz.getDeclaredFields();
		if ( fields != null && fields.length > 0 )
		{
			for ( Field field : fields )
			{
				if ( field.isAnnotationPresent( Column.class ) )
				{
					Column column = field.getAnnotation( Column.class );
					String columnName = column.value();
					describes.add( new ColumnDescribe( columnName, null, field ) );
				}
			}
		}
		return describes;
	}

	public static List< ColumnDescribe > parseColumnsData( Object obj )
	{
		List< ColumnDescribe > describes = new ArrayList< ColumnDescribe >();
		Field[] fields = obj.getClass().getDeclaredFields();
		if ( fields != null && fields.length > 0 )
		{
			for ( Field field : fields )
			{
				try
				{
					if ( field.isAnnotationPresent( Column.class ) )
					{
						field.setAccessible( true );
						Column column = field.getAnnotation( Column.class );
						if ( !column.primary() )
						{
							Object value = field.get( obj );
							if ( value != null )
							{
								String columnName = column.value();
								describes.add( new ColumnDescribe( columnName, value, field ) );
							}
						}
					}
				}
				catch ( Exception e )
				{
					e.printStackTrace();
				}
			}
		}
		return describes;
	}

	public static < T > List< T > parseResult( ResultSet rs, Class< T > clazz )
	{
		return parseResult( rs, parseColumnsData( clazz ), clazz );
	}

	public static < T > List< T > parseResult( ResultSet rs, List< ColumnDescribe > describes,
					Class< T > clazz )
	{
		List< T > list = new ArrayList< T >();
		try
		{
			if ( rs != null && describes != null && describes.size() > 0 )
			{
				// 展开结果集数据库
				while ( rs.next() )
				{
					T value = clazz.newInstance();
					for ( ColumnDescribe describe : describes )
					{
						// 通过字段检索
						Field field = describe.getField();
						field.setAccessible( true );
						field.set( value, rs.getObject( describe.getColumn() ) );
					}
					list.add( value );
				}
			}
		}
		catch ( Exception e )
		{
			e.printStackTrace();
		}
		return list;
	}
}
